<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BOCJoinService
 *
 * @author I062261
 */
class BOCJoinService extends BOperationContract {

    const Operation_JoinService = 'joinService';

    protected function registerOperationContext($operation = NULL, $receiver = NULL, $sender = NULL) {

        if ($operation == NULL && $this->operationName == NULL)
            $this->operationName = self::Operation_JoinService;

        if (!isset($this->operations[self::Operation_JoinService]['receiverContext']['data']))
            $this->operations[self::Operation_JoinService]['receiverContext']['data'] = array();

        $serviceEngineId = Blyn::app()->getActiveService()->getServiceEngine()->getId();

//serviceEngine will handle the request
        $this->operations[self::Operation_JoinService]['receiverContext'][self::ReceiverContext_ServiceApp] = self::Context_Value_FixedValue;
        $this->operations[self::Operation_JoinService]['receiverContext']['data'] =
                array_merge($this->operations[self::Operation_JoinService]['receiverContext']['data'], array('serviceAppId' => $serviceEngineId));

        if (isset($this->operations[self::Operation_JoinService]['receiverContext']['data']['serviceId']))
            $receiver['serviceId'] = $this->operations[self::Operation_JoinService]['receiverContext']['data']['serviceId'];

        if (isset($receiver['serviceId'])) {
//service is specified in runtime
            $this->operations[self::Operation_JoinService]['receiverContext'][self::ReceiverContext_Service] =
                    self::Context_Value_RuntimeValue;

            //$service = new BService($receiver['serviceId']);

            if (isset($receiver['role'])) {
//service is specified in runtime                

                if (is_string($receiver['role'])) {

                    $service = new BService($receiver['serviceId']);

//specify default role of workteam member as receiver user
                    $authManager = $service->getServiceEngine()->getAuthManager();
                    $roleId = $authManager->getRoleId($receiver['role']);
                    $this->operations[self::Operation_JoinService]['receiverContext'][self::ReceiverContext_User] = self::Context_Value_UserType_Role;
                    $this->operations[self::Operation_JoinService]['receiverContext']['data'] =
                            array_merge($this->operations[self::Operation_JoinService]['receiverContext']['data'], array('roleId' => $roleId));
                }
            }
        }
    }

    public function sendOperationRequest($operation, $receiver = null, $sender = NULL) {

        $this->parseOperationRequest($operation, $receiver, $sender);

//by default, if do not setup receiver, sen
//admin of site can send message to all user
        if ($this->operationName == self::Operation_JoinService) {
            return parent::sendOperationRequest($operation, $receiver, $sender);
        }

        return FALSE;
    }

    /**
     * this function is called before send request
     * @param type $operation
     * @param type $operationData
     * @param type $receiver
     * @param type $sender
     * @return type
     */
    public function checkSenderPermit($operation, $sender = array(), $receiver = array()) {

        if (!isset($operation['data']['applyingRole']))
            return parent::checkSenderPermit($operation, $sender, $receiver);

        if ($this->checkSenderPermitResult == 'not-checked') {

            $receiver_app = BServiceApp::getInstanceById($receiver['serviceAppId']);

            $applyingRoleName = $operation['data']['applyingRole'];

            $authManager = $receiver_app->getAuthManager();

            $applyingRoleId = $authManager->getRoleId($applyingRoleName);

            $permits = $this->getOperationPermits($operation['name'], 'senderPermit', $receiver);

            $this->checkSenderPermitResult = FALSE;

            foreach ($permits as $roleName => $roleData) {
                if (parent::checkPermit(array($roleName), $sender)) {
                    $accessRoleIdList = $authManager->getRoleIdList($roleData);
                    if (in_array($applyingRoleId, $accessRoleIdList)) {
                        $this->checkSenderPermitResult = TRUE;
                        break;
                    }
                }
            }
        }

        return $this->checkSenderPermitResult;
    }

    protected function checkAutoProcessSenderPermit($operation, $receiver = array(), $sender = array()) {

        if ($this->checkAutoProcessSenderPermitResult == 'not-checked') {

            $receiver_app = BServiceApp::getInstanceById($receiver['serviceAppId']);

            $authManager = $receiver_app->getAuthManager();

            $applyingRole = $operation['data']['applyingRole'];

            $permits = $this->getOperationPermits($operation['name'], 'autoProcessSenderPermit', $receiver);

            $this->checkAutoProcessSenderPermitResult = FALSE;

            foreach ($permits as $roleName => $roleData) {
                if (parent::checkPermit(array($roleName), $sender)) {
//$accessRoleIdList = $authManager->getRoleIdList($roleData);
                    if (in_array($applyingRole, $roleData)) {
                        $this->checkAutoProcessSenderPermitResult = TRUE;
                        break;
                    }
                }
            }
        }

        return $this->checkAutoProcessSenderPermitResult;
    }

    /**
     * autoProcess will automatically add sender into service
     * @param type $requestId
     * @param type $operation
     * @param type $receiver
     * @param type $sender
     * @return boolean
     */
    protected function autoProcessRequest($requestId, $operation = null, $receiver = null, $sender = NULL) {
//parent::autoProcessRequest($requestId, $operation, $receiver, $sender);
        $sAppId = $receiver['serviceAppId'];
        //adding to receiver's service
        $serviceId = $receiver['serviceId'];
        //add to sender into service
        $userId = $sender['userId'];
        $applyingRole = $operation['data']['applyingRole'];
        //$userId = Blyn::app()->getCurrentUser()->getId();

        $sApp = BServiceApp::getInstanceById($sAppId);

        $result = $sApp->doOperation($operation['name'], array('serviceId' => $serviceId, 'applyingRole' => $applyingRole, 'userId' => $userId));

        if ($result) {
            $this->updateOperationRequestData($requestId, array('status' => 'autoProcessed'));
            return TRUE;
        }

        return FALSE;
    }

    public function processRequest($requestId, $operation = null, $receiver = null, $sender = NULL) {

        return $this->autoProcessRequest($requestId, $operation, $receiver, $sender);
    }

}

?>
